home *** CD-ROM | disk | FTP | other *** search
- #include <conio.h>
- #include <dos.h>
- #include <mem.h>
-
- #include "xstubs.h"
- #include "xinternl.h"
- /*==================================================================
- XMAIN.CPP contains the basic setup variables and functions for the
- XLIB package.
-
- These routines were written initially by Themie Gouthas and
- company and modified March 1995 by Victor B. Putz.
- ===================================================================*/
-
-
- /*==================================================================
- This contains variables that really belong to other functions,
- but we'll define them here
- ===================================================================*/
-
- int VsyncHandlerActive = 0;
- int MouseRefreshFlag = 0;
- int MouseVsyncHandler = 0;
- int WaitingStartLow = 0;
- int WaitingStartHigh = 0;
- int WaitingPelPan = 0;
- int VsyncPaletteStart = 0;
- int VsyncPaletteCount = 0;
-
-
-
-
- /*==================================================================
- This block contains variable declarations for the xlib routines
- ===================================================================*/
- BYTE InGraphics = 0; /* non zero if in X graphics mode */
- int CurrXMode = 0; /* contains current X graphics mode id */
- int ScrnPhysicalByteWidth = 0; /* Physical screen width in bytes */
- xScreenCoord_t ScrnPhysicalPixelWidth = 0; /* Physical screen width in pixels */
- xScreenCoord_t ScrnPhysicalHeight = 0; /* Physical screen height in pixels */
- int ErrorValue = 0; /* Error return value */
- xPageHandle_t SplitScrnOffs = 0; /* Offset in VRAM of split screen */
- xScreenCoord_t SplitScrnScanLine = 0; /* Scan line split screen starts at */
- /* initially. Resizing the split scrn */
- /* using the other functions does not */
- /* change this value */
- int SplitScrnVisibleHeight = 0; /* Height of the visible portion of the*/
- /* split screen. */
- xPageHandle_t Page0_Offs = 0; /* Offset in VRAM of main virt. screen */
- xPageHandle_t Page1_Offs = 0; /* Offset in VRAM of 2nd virt. screen */
- xPageHandle_t Page2_Offs = 0; /* Offset in VRAM of 3rd virt. screen */
- int ScrnLogicalByteWidth = 0; /* Virtual screen width in bytes */
- xScreenCoord_t ScrnLogicalPixelWidth = 0; /* Virtual screen width in pixels */
- xScreenCoord_t ScrnLogicalHeight = 0; /* Virtual screen height in pixels */
- xScreenCoord_t MaxScrollX = 0; /* Max X position of physical screen */
- /* within virtual screen */
- xScreenCoord_t MaxScrollY = 0; /* Max Y position of physical screen */
- /* within virtual screen */
- int DoubleBufferActive = 0; /* Indicates whether double buffering */
- /* is active */
- int TrippleBufferActive = 0; /* Indicates whether tripple */
- /* buffering is active */
- int VisiblePageIdx = 0; /* Index number of visible page 0 or 1 */
- xPageHandle_t HiddenPageOffs = 0; /* Offset of Hidden Pg | only valid */
- xPageHandle_t VisiblePageOffs = 0; /* Offset of Visible Pg| for D.B. mode */
- xPageHandle_t WaitingPageOffs = 0; /* Offset of Waiting Pg| for T.B. mode */
- xPageHandle_t NonVisual_Offs = 0; /* Offset of first non-visible VRAM */
-
- int StartAddressFlag = 0;
-
- xScreenCoord_t TopClip = 0; /* Clipping rectangle */
- xScreenCoord_t BottomClip = 0;
- xScreenCoord_t LeftClip = 0;
- xScreenCoord_t RightClip = 0;
-
- xScreenCoord_t PhysicalStartPixelX = 0; /* Coordinates of physical (visible) */
- int PhysicalStartByteX = 0; /* screen relative to the virtual */
- xScreenCoord_t PhysicalStartY = 0; /* screen's U.L. corner */
-
- unsigned char SplitScrnActive = 0;
-
- char VsyncPaletteBuffer[ 768 ];
-
- unsigned char * pbVGABuffer = (unsigned char *)(0xA000 << 4);
-
- void x_set_start_addr( xScreenCoord_t, xScreenCoord_t );
-
- /*
- ZeroOutParameters() zeros out all the xlib variables.
- */
- void ZeroOutParameters(
- void
- )
- {
- InGraphics = 0; /* non zero if in X graphics mode */
- CurrXMode = 0; /* contains current X graphics mode id */
- ScrnPhysicalByteWidth = 0; /* Physical screen width in bytes */
- ScrnPhysicalPixelWidth = 0; /* Physical screen width in pixels */
- ScrnPhysicalHeight = 0; /* Physical screen height in pixels */
- ErrorValue = 0; /* Error return value */
- SplitScrnOffs = 0; /* Offset in VRAM of split screen */
- SplitScrnScanLine = 0; /* Scan line split screen starts at */
- /* initially. Resizing the split scrn */
- /* using the other functions does not */
- /* change this value */
- SplitScrnVisibleHeight = 0; /* Height of the visible portion of the*/
- /* split screen. */
- Page0_Offs = 0; /* Offset in VRAM of main virt. screen */
- Page1_Offs = 0; /* Offset in VRAM of 2nd virt. screen */
- Page2_Offs = 0; /* Offset in VRAM of 3rd virt. screen */
- ScrnLogicalByteWidth = 0; /* Virtual screen width in bytes */
- ScrnLogicalPixelWidth = 0; /* Virtual screen width in pixels */
- ScrnLogicalHeight = 0; /* Virtual screen height in pixels */
- MaxScrollX = 0; /* Max X position of physical screen */
- /* within virtual screen */
- MaxScrollY = 0; /* Max Y position of physical screen */
- /* within virtual screen */
- DoubleBufferActive = 0; /* Indicates whether double buffering */
- /* is active */
- TrippleBufferActive = 0; /* Indicates whether tripple */
- /* buffering is active */
- VisiblePageIdx = 0; /* Index number of visible page 0 or 1 */
- HiddenPageOffs = 0; /* Offset of Hidden Pg | only valid */
- VisiblePageOffs = 0; /* Offset of Visible Pg| for D.B. mode */
- WaitingPageOffs = 0; /* Offset of Waiting Pg| for T.B. mode */
- NonVisual_Offs = 0; /* Offset of first non-visible VRAM */
-
- StartAddressFlag = 0;
-
- TopClip = 0; /* Clipping rectangle */
- BottomClip = 0;
- LeftClip = 0;
- RightClip = 0;
-
- PhysicalStartPixelX = 0; /* Coordinates of physical (visible) */
- PhysicalStartByteX = 0; /* screen relative to the virtual */
- PhysicalStartY = 0; /* screen's U.L. corner */
-
- for ( int i = 0; i < 768; ++i ) {
- VsyncPaletteBuffer[ i ] = 0;
- }
- }
-
- BYTE PelPanMask[ ] = {
- 0x00,
- 0x02,
- 0x04,
- 0x06
- };
-
- BYTE DoubleScanFlag = 0;
-
- inline void WaitVsyncStart(
- void
- )
- {
- while( inp( INPUT_STATUS_0 ) & 0x08 );
- while( !( inp( INPUT_STATUS_0 ) & 0x08 ) );
- }
-
- /*==================================================================
- The following sets of arrays are the register parameters to set up
- the various x modes.
- ===================================================================*/
- struct XSetup_t {
- int iWidth;
- int iHeight;
- int iDotClock;
- int iNumRegisters;
- int aiRegisterValues[];
- };
-
- XSetup_t X256Y200 = {
- 256,
- 200,
- 0x0e3,
- 8,
- {
- 0x5f00, //horz total
- 0x3f01, //horz displayed
- 0x4202, //start horz blanking
- 0x9f03, //end horz blanking
- 0x4c04, //start h sync
- 0x0005, //end h sync
- 0x0014, //turn off dword mode
- 0xe317 //turn on byte mode
- }
- };
-
- XSetup_t X256Y240 = {
- 256,
- 240,
- 0x0e3,
- 16,
- {
- 0x5f00, //horz total
- 0x3f01, //horz displayed
- 0x4202, //start horz blanking
- 0x9f03, //end horz blanking
- 0x4c04, //start h sync
- 0x0005, //end h sync
- 0x0d06, //vertical total
- 0x3e07, //overflow (bit 8 of vertical counts)
- 0x4109, //cell height (2 to double-scan)
- 0xea10, //v sync start
- 0xac11, //v sync end and protect cr0-cr7
- 0xdf12, //vertical displayed
- 0x0014, //turn off dword mode
- 0xe715, //v blank start
- 0x0616, //v blank end
- 0xe317 //turn on byte mode
- }
- };
-
- XSetup_t X320Y200 = {
- 320,
- 200,
- 0,
- 2,
- {
- 0x0014, //Turn off dword mode
- 0xe317 //Turn on byte mode
- }
- };
-
- XSetup_t X320Y240 = {
- 320,
- 240,
- 0x0e3,
- 10,
- {
- 0x0d06, //vertical total
- 0x3e07, //overflow (bit 8 of vertical counts)
- 0x4109, //cell height (2 to double-scan)
- 0xea10, //v sync start
- 0xac11, //v sync end and protect cr0-cr7
- 0xdf12, //vertical displayed
- 0x0014, //turn off dword mode
- 0xe715, //v blank start
- 0x0616, //v blank end
- 0xe317 //turn on byte mode
- }
- };
-
- XSetup_t X360Y200 = {
- 360,
- 200,
- 0x0e7,
- 8,
- {
- 0x6b00, //horz total
- 0x5901, //horz displayed
- 0x5a02, //start horz blanking
- 0x8e03, //end horz blanking
- 0x5e04, //start h sync
- 0x8a05, //end h sync
- 0x0014, //turn off dword mode
- 0xe317 //turn on byte mode
- }
- };
-
- XSetup_t X360Y240 = {
- 360,
- 240,
- 0x0e7,
- 17,
- {
- 0x6b00, //horz total
- 0x5901, //horz displayed
- 0x5a02, //start horz blanking
- 0x8e03, //end horz blanking
- 0x5e04, //start h sync
- 0x8a05, //end h sync
- 0x0d06, //vertical total
- 0x3e07, //overflow (bit 8 of vertical counts)
- 0x4109, //cell height (2 to double-scan)
- 0xea10, //v sync start
- 0xac11, //v sync end and protect cr0-cr7
- 0xdf12, //vertical displayed
- 0x2d13, //offset;
- 0x0014, //turn off dword mode
- 0xe715, //v blank start
- 0x0616, //v blank end
- 0xe317 //turn on byte mode
- }
- };
-
-
- XSetup_t X376Y282 = {
- 376,
- 282,
- 0x0e7,
- 18,
- {
- 0x6e00, //horz total
- 0x5d01, //horz displayed
- 0x5e02, //start horz blanking
- 0x9103, //end horz blanking
- 0x6204, //start h sync
- 0x8f05, //end h sync
- 0x6206, //vertical total
- 0xf007, //overflow
- 0x6109, //cell height
- 0x310f, //Unknown?-->VPutz
- 0x3710, //v sync start
- 0x8911, //v sync end and protect cr0-cr7
- 0x3312, //vertical displayed
- 0x2f13, //offset
- 0x0014, //turn off dword mode
- 0x3c15, //v blank start
- 0x5c16, //v blank end
- 0xe317 //turn on byte mode
- }
- };
-
- XSetup_t X256Y400 = {
- 256,
- 400,
- 0x0e3,
- 8,
- {
- 0x5f00, //horz total
- 0x3f01, //horz displayed
- 0x4202, //start horz blanking
- 0x9f03, //end horz blanking
- 0x4c04, //start h sync
- 0x0005, //end h sync
- 0x4009, //cell height
- 0x0014, //turn off dword mode
- 0xe317 //turn on byte mode
- }
- };
-
- XSetup_t X256Y480 = {
- 256,
- 480,
- 0x0e3,
- 16,
- {
- 0x5f00, //horz total
- 0x3f01, //horz displayed
- 0x4202, //start horz blanking
- 0x9f03, //end horz blanking
- 0x4c04, //start h sync
- 0x0005, //end h sync
- 0x0d06, //vertical total
- 0x3e07, //overflow (bit 8 of vertical counts)
- 0x4009, //cell height (2 to double-scan)
- 0xea10, //v sync start
- 0xac11, //v sync end and protect cr0-cr7
- 0xdf12, //vertical displayed
- 0x0014, //turn off dword mode
- 0xe715, //v blank start
- 0x0616, //v blank end
- 0xe317 //turn on byte mode
- }
- };
-
-
- XSetup_t X320Y400 = {
- 320,
- 400,
- 0x0e3,
- 3,
- {
- 0x4009, //cell height
- 0x0014, //turn off dword mode
- 0xe317 //turn on byte mode
- }
- };
-
- XSetup_t X320Y480 = {
- 320,
- 480,
- 0x0e3,
- 10,
- {
- 0x0d06, //vertical total
- 0x3e07, //overflow (bit 8 of vertical counts)
- 0x4009, //cell height (2 to double-scan)
- 0xea10, //v sync start
- 0xac11, //v sync end and protect cr0-cr7
- 0xdf12, //vertical displayed
- 0x0014, //turn off dword mode
- 0xe715, //v blank start
- 0x0616, //v blank end
- 0xe317 //turn on byte mode
- }
- };
-
- XSetup_t X360Y400 = {
- 360,
- 400,
- 0x0e7,
- 9,
- {
- 0x6b00, //horz total
- 0x5901, //horz displayed
- 0x5a02, //start horz blanking
- 0x8e03, //end horz blanking
- 0x5e04, //start h sync
- 0x8a05, //end h sync
- 0x4009, //cell height
- 0x0014, //turn off dword mode
- 0xe317 //turn on byte mode
- }
- };
-
- XSetup_t X360Y480 = {
- 360,
- 480,
- 0x0e7,
- 17,
- {
- 0x6b00, //horz total
- 0x5901, //horz displayed
- 0x5a02, //start horz blanking
- 0x8e03, //end horz blanking
- 0x5e04, //start h sync
- 0x8a05, //end h sync
- 0x0d06, //vertical total
- 0x3e07, //overflow
- 0x4009, //cell height
- 0xea10, //v sync start
- 0xac11, //v sync end and protect cr0-cr7
- 0xdf12, //vertical displayed
- 0x2d13, //offset
- 0x0014, //turn off dword mode
- 0xe715, //v blank start
- 0x0616, //v blank end
- 0xe317 //turn on byte mode
- }
- };
-
- XSetup_t X360Y360 = {
- 360,
- 360,
- 0x0e7,
- 15,
- {
- 0x6b00, //horz total
- 0x5901, //horz displayed
- 0x5a02, //start horz blanking
- 0x8e03, //end horz blanking
- 0x5e04, //start h sync
- 0x8a05, //end h sync
- 0x4009, //cell height
- 0x8810, //v sync start
- 0x8511, //v sync end and protect cr0-cr7
- 0x6712, //vertical displayed
- 0x2d13, //offset
- 0x0014, //turn off dword mode
- 0x6d15, //v blank start
- 0xba16, //v blank end
- 0xe317 //turn on byte mode
- }
- };
-
- XSetup_t X376Y308 = {
- 376,
- 308,
- 0x0e7,
- 18,
- {
- 0x6e00, //horz total
- 0x5d01, //horz displayed
- 0x5e02, //start horz blanking
- 0x9103, //end horz blanking
- 0x6204, //start h sync
- 0x8f05, //end h sync
- 0x6206, //vertical total
- 0x0f07, //overflow
- 0x4009, //Unknown?-->VPutz
- 0x310f, //Unknown?-->VPutz
- 0x3710, //v sync start
- 0x8911, //v sync end and protect cr0-cr7
- 0x3312, //vertical displayed
- 0x2f13, //offset
- 0x0014, //turn off dword mode
- 0x3c15, //v blank start
- 0x5c16, //v blank end
- 0xe317 //turn on byte mode
- }
- };
-
- XSetup_t X376Y564 = {
- 376,
- 564,
- 0x0e7,
- 18,
- {
- 0x6e00, //horz total
- 0x5d01, //horz displayed
- 0x5e02, //start horz blanking
- 0x9103, //end horz blanking
- 0x6204, //start h sync
- 0x8f05, //end h sync
- 0x6206, //vertical total
- 0xf007, //overflow
- 0x6009, //Unknown?-->VPutz
- 0x310f, //Unknown?-->VPutz
- 0x3710, //v sync start
- 0x8911, //v sync end and protect cr0-cr7
- 0x3312, //vertical displayed
- 0x2f13, //offset
- 0x0014, //turn off dword mode
- 0x3c15, //v blank start
- 0x5c16, //v blank end
- 0xe317 //turn on byte mode
- }
- };
-
- XSetup_t * apSetupTable[] = {
- &X320Y200,
- &X320Y240,
- &X360Y200,
- &X360Y240,
- &X376Y282,
- &X320Y400,
- &X320Y480,
- &X360Y400,
- &X360Y480,
- &X360Y360,
- &X376Y308,
- &X376Y564,
- &X256Y200,
- &X256Y240
- };
-
-
- /*==================================================================
- Now begins the actual "mock xlib" routines.
- ===================================================================*/
-
- /*
- SetLogicalScreenWidth() sets the logical page width.
- */
- void SetLogicalScreenWidth(
- xScreenCoord_t iNewLogicalWidth
- )
- {
- //first round to the last multiple of 8
- iNewLogicalWidth &= ( ~0x0f );
- outp( CRTC_INDEX, CRTC_OFFSET );
- if ( iNewLogicalWidth < ScrnPhysicalPixelWidth ) {
- iNewLogicalWidth = ScrnPhysicalPixelWidth;
- }
- outp( CRTC_INDEX + 1, iNewLogicalWidth / 8 );
- ScrnLogicalByteWidth = iNewLogicalWidth / 4;
- RightClip = iNewLogicalWidth / 4;
- MaxScrollX = iNewLogicalWidth - ( iNewLogicalWidth / 4 - ScrnPhysicalByteWidth ) * 4;
- ScrnLogicalPixelWidth = iNewLogicalWidth;
- ScrnLogicalHeight = ( 0xffff / ScrnLogicalByteWidth );
- BottomClip = ScrnLogicalHeight;
- MaxScrollY = ScrnLogicalHeight - ScrnPhysicalHeight;
- NonVisual_Offs = ScrnLogicalByteWidth * ScrnPhysicalHeight;
- }
-
- /*
- ClearVideoMemory() zeros all video memory by selecting all
- planes and writing zero to the whole segment.
- */
- void ClearVideoMemory(
- void
- )
- {
- outpw(SC_INDEX, ALL_PLANES);
- memset( pbVGABuffer, 0x0, 0x10000);
- }
-
- #define LAST_X_MODE 13
- /*
- x_set_mode() sets the valid graphics mode.
- */
- int x_set_mode(
- int iGraphicsMode,
- xScreenCoord_t iNewLogicalWidth
- )
- {
- ZeroOutParameters();
- //if we've selected an invalid mode, exit
- if ( LAST_X_MODE <= iGraphicsMode ) {
- InGraphics = FALSE;
- return -1;
- }
- //set the current graphics mode flags
- CurrXMode = iGraphicsMode;
- InGraphics = TRUE;
- if ( iGraphicsMode <= 3 ) {
- DoubleScanFlag = TRUE;
- }
- else {
- DoubleScanFlag = FALSE;
- }
- ClearVideoMemory();
- //set base x mode
- union REGS r;
- r.x.eax = 0x0013;
- int386(0x10, &r, &r);
- outpw( SC_INDEX, 0x0604 );
- outpw( SC_INDEX, 0x0100 );
- //Set the dot clock scanning rate, if applicable
- XSetup_t * pSetup = apSetupTable[ iGraphicsMode ];
- if ( pSetup->iDotClock != 0 ) {
- outp( MISC_OUTPUT, pSetup->iDotClock );
- }
- //Undo reset (restart sequencer)
- outpw( SC_INDEX, 0x0300 );
- //Reprogram the CRT controller. The VSync End register contains
- //the register write-protect bit, so we save the old value, mask
- //out the write-protect bit, and rewrite the value
- outp( CRTC_INDEX, 0x11 );
- int iTemp = inp( CRTC_INDEX + 1 );
- outp( CRTC_INDEX, 0x11 );
- outp( CRTC_INDEX + 1, iTemp & 0x07f );
- //now that we've removed the write-protection, we reset all the
- //appropriate CRT registers
- for ( int i = 0; i < pSetup->iNumRegisters; ++i ) {
- outpw( CRTC_INDEX, pSetup->aiRegisterValues[ i ] );
- }
- ClearVideoMemory();
- //set screen dimensions
- ScrnPhysicalPixelWidth = pSetup->iWidth;
- SplitScrnScanLine = pSetup->iWidth;
- ScrnPhysicalByteWidth = ScrnPhysicalPixelWidth / 4;
- ScrnPhysicalHeight = pSetup->iHeight;
- //our base X mode is set. Now reset the logical screen width
- SetLogicalScreenWidth( iNewLogicalWidth );
- // ClearVideoMemory();
- return 0;
- }
-
- /*
- @func Enables Read/Write access to a plane using general memory access
- methods.
- */
- void x_select_default_plane(
- unsigned char bPlane //@parm Plane to write to
- )
- {
- bPlane &= 0x03; //mask out so we only have 0-3 to choose from
- int iTemp = 0x0100;
- iTemp <<= bPlane; //set only the correct bit to 1
- iTemp += MAP_MASK; //set the map mask
- //Select the write plane
- outpw( SC_INDEX, iTemp );
- //Select the read plane
- iTemp = bPlane << 8;
- iTemp += READ_MAP;
- outpw( GC_INDEX, iTemp );
- }
-
- /*
- @func internal function called to set the split screen scan line,
- used by several functions.
- */
- void _ScanLineBoogie(
- xScreenCoord_t wScanLine
- )
- {
- //now play with scan line magic
- if ( DoubleScanFlag ) {
- wScanLine *= 2;
- wScanLine -= 1;
- }
- WaitVsyncStart();
- //disable interrupts until the controller is set up
- _disable();
- //output bits 0-7 of the split screen scan line
- outpw( CRTC_INDEX, (( int )wScanLine << 8) + LINE_COMPARE );
- //bit 4 of overflow register == bit 8 of split screen scan line (!?),
-
- //so read the overflow register and set the appropriate bit.
- outp( CRTC_INDEX, OVERFLOW );
- int iPortTemp = inp( CRTC_INDEX + 1 );
- iPortTemp &= ~( 0x10 ); //clear out bit 5
- //now set bit 5 to bit 8 of the split screen scan line
- iPortTemp |= ((( unsigned char )( wScanLine >> 8 )) & 1 ) << 4;
- //and finally output that value to the port.
- outp( CRTC_INDEX + 1, iPortTemp );
- //unfortunately, bit 6 of max scan line register =
- //bit 9 of split screen scan line... here we go again...
- int iTemp = ( (int)wScanLine )& ( 0x02 << 8 );
- iTemp >>= 3; //move bit 9 into bit 6 position
- outp( CRTC_INDEX, MAX_SCAN_LINE );
- iPortTemp = inp( CRTC_INDEX + 1 );
- iPortTemp &= ~( 0x40 ); //clear out bit 6
- iPortTemp |= iTemp;
- outp( CRTC_INDEX, MAX_SCAN_LINE );
- outp( CRTC_INDEX + 1, iPortTemp );
- //enable interrupts again
- _enable();
-
- }
-
- /*
- @func x_set_splitscreen enables the split screen section at the bottom of the
- physical screen; good for scores, etc.
- */
- void x_set_splitscreen(
- xScreenCoord_t wScanLine //@parm First scan line of the split screen on the display
- )
- {
- if ( DoubleBufferActive ) {
- ErrorValue = ERROR;
- return;
- }
- if ( SplitScrnActive ) {
- ErrorValue = ERROR;
- return;
- }
- //turn on split screen pel pan suppression so the split screen
- //isn't panned as is the non split screen portion.
- //First reset the AC Index/Data toggle to index state
- int iPortTemp = inp( INPUT_STATUS_0 );
- //Send bit 5 to prevent screen blanking
- outp( AC_INDEX, AC_MODE_CONTROL + 0x20 );
- //get the current AC mode control reg
- iPortTemp = inp( AC_INDEX + 1 );
- //Enable split screen pel panning suppression
- iPortTemp |= 0x20;
- outp( AC_INDEX, iPortTemp );
- //now reset parameters
- PhysicalStartByteX = 0;
- PhysicalStartPixelX = 0;
- PhysicalStartY = 0;
- SplitScrnActive = TRUE;
- if ( wScanLine < 0 ) {
- wScanLine = 0;
- }
- if ( wScanLine > ScrnPhysicalHeight ) {
- wScanLine = ScrnPhysicalHeight;
- }
- SplitScrnScanLine = wScanLine;
- _ScanLineBoogie( wScanLine );
- SplitScrnVisibleHeight = ScrnPhysicalHeight - SplitScrnScanLine;
- //now set all pages to begin after split screen memory
- Page0_Offs = ScrnLogicalByteWidth * SplitScrnVisibleHeight;
- Page1_Offs = Page0_Offs;
- Page2_Offs = Page0_Offs;
- VisiblePageOffs = HiddenPageOffs = Page0_Offs;
- //calculate # of non-split-screen rows in video ram
- int iNonSplitScreenBytes = 0xffff - Page0_Offs;
- int iNonSplitScreenRows = iNonSplitScreenBytes / ScrnLogicalByteWidth;
- ScrnLogicalHeight = iNonSplitScreenRows;
- if ( BottomClip > ScrnLogicalHeight ) {
- BottomClip = ScrnLogicalHeight;
- }
- MaxScrollY = ScrnLogicalHeight - SplitScrnScanLine;
- x_set_start_addr( 0, 0 );
- }
-
-
- /*
- @func Swaps visible and hidden page offsets and then
- executes SetStartAddr to achieve a page flip. See <f x_set_start_addr>.
- */
- void x_page_flip(
- xScreenCoord_t wX, //@parm X coord of new page position
- xScreenCoord_t wY //@parm Y coord of new page position
- )
- {
- if ( DoubleBufferActive ) {
- int iTemp = HiddenPageOffs;
- HiddenPageOffs = VisiblePageOffs;
- VisiblePageOffs = iTemp;
- //simulate a XOR
- if ( VisiblePageIdx & 0x01 ) {
- VisiblePageIdx |= ~0x01;
- }
- else {
- VisiblePageIdx |= 0x01;
- }
- }
- if ( TrippleBufferActive ) {
- int iTemp = HiddenPageOffs;
- HiddenPageOffs = VisiblePageOffs;
- VisiblePageOffs = WaitingPageOffs;
- WaitingPageOffs = iTemp;
- ++VisiblePageIdx;
- if ( VisiblePageIdx >= 3 ) {
- VisiblePageIdx = 0;
- }
- }
- x_set_start_addr( wX, wY );
- }
-
- /*
- @func Sets the starting address of the physical visible page
- in logical screen memory.
- */
- void x_set_start_addr(
- xScreenCoord_t wX, //@parm X coord of new start address
- xScreenCoord_t wY //@parm Y coord of new start address
- )
- {
- int iOffset = ScrnLogicalByteWidth * wY;
- if ( DoubleBufferActive || TrippleBufferActive ) {
- iOffset += VisiblePageOffs;
- }
- else {
- iOffset += Page0_Offs;
- }
- PhysicalStartPixelX = wX;
- PhysicalStartY = wY;
- PhysicalStartByteX = wX / 4;
- iOffset += PhysicalStartByteX;
-
- int iLowAddress = ( iOffset << 8 ) + ADDR_LOW;
- int iHighAddress = ( iOffset & ( 0xFF << 8 ) ) + ADDR_HIGH;
- int iPelPanSetup = ( PelPanMask[ wX & 0x03 ] << 8 ) + (PEL_PANNING + 0x20);
- if ( VsyncHandlerActive ) {
- while ( StartAddressFlag ) {
- //do nothing; wait until address flag is clear
- }
- //disable interrupts
- _disable();
- WaitingStartLow = iLowAddress;
- WaitingStartHigh = iHighAddress;
- WaitingPelPan = iPelPanSetup;
- StartAddressFlag = 1;
- //reenable interrupts
- _enable();
- return;
- }
- //wait for display enable to be on
- while ( inp( INPUT_STATUS_0 ) & 0x01 );
- //now set up the new start address
- _disable();
- outpw( CRTC_INDEX, iLowAddress );
- outpw( CRTC_INDEX, iHighAddress );
- _enable();
- //now wait for trailing edge of vertical sync so the other page will
- //be invisible when we start drawing to it
- while( !( inp( INPUT_STATUS_0 ) & 0x08 ) );
- _disable();
- outp( AC_INDEX, iPelPanSetup & 0xff ); //lo byte
- outp( AC_INDEX, iPelPanSetup >> 8 ); //hi byte
- _enable();
- return;
- }
-
- /*
- @func hides the split screen from display.
- */
- void x_hide_splitscreen(
- void
- )
- {
- if ( !SplitScrnActive || ( CurrXMode > 4 )) {
- ErrorValue = ERROR;
- return;
- }
- MaxScrollY = ScrnLogicalHeight - ScrnPhysicalHeight;
- SplitScrnVisibleHeight = 0;
- _ScanLineBoogie( ScrnPhysicalHeight );
- ErrorValue = OK;
- }
-
- /*
- @func shows the split screen at its earlier position.
- Only use this if SplitScrnLine hs been set, and do not use in
- graphics modes above 4, since it will do nothing.
- */
- void x_show_splitscreen(
- void
- )
- {
- if ( !SplitScrnActive || ( CurrXMode > 4 )) {
- ErrorValue = ERROR;
- return;
- }
- MaxScrollY = ScrnLogicalHeight - SplitScrnScanLine;
- SplitScrnVisibleHeight = ScrnPhysicalHeight - SplitScrnScanLine;
- _ScanLineBoogie( SplitScrnScanLine );
- ErrorValue = OK;
- }
-
-
- /*
- @func Adjusts the split screen scan line to a given value;
- only to be used if split screen has been initializes; will not
- function for modes above 4.
- */
- void x_adjust_splitscreen(
- xScreenCoord_t wScanLine //@parm New scan line to begin displaying split screen
- )
- {
- if ( !SplitScrnActive ||
- ( CurrXMode > 4 ) ||
- ( wScanLine < SplitScrnScanLine ) ) {
- ErrorValue = ERROR;
- return;
- }
- MaxScrollY = ScrnLogicalHeight - wScanLine;
- SplitScrnVisibleHeight = ScrnPhysicalHeight - wScanLine;
- _ScanLineBoogie( wScanLine );
- ErrorValue = OK;
- }
-
-
- /*
- @func enables double-buffering on the mode X vga memory.
- */
- int x_set_doublebuffer(
- int wPageHeight //@parm Height of each page in scan lines
- )
- {
- if ( DoubleBufferActive ) {
- ErrorValue = ERROR;
- return ERROR;
- }
- //visible page = 0;
- VisiblePageIdx = 0;
- //find if we're requesting a valid page height
- if ( wPageHeight > ( ScrnLogicalHeight / 2 ) ) {
- wPageHeight = ScrnLogicalHeight / 2;
- }
- //set the new logical height
- ScrnLogicalHeight = wPageHeight;
- if ( BottomClip > ScrnLogicalHeight ) {
- BottomClip = ScrnLogicalHeight;
- }
- int iPageSize = ScrnLogicalHeight * ScrnLogicalByteWidth;
- VisiblePageOffs = Page0_Offs;
- Page1_Offs = HiddenPageOffs = Page0_Offs + iPageSize;
- NonVisual_Offs = Page1_Offs + iPageSize;
- DoubleBufferActive = TRUE;
- MaxScrollY = ScrnLogicalHeight - ScrnPhysicalHeight - SplitScrnVisibleHeight;
- ErrorValue = OK;
- return OK;
- }
-
-
- /*
- @func enables triple-buffering on the mode X vga memory screen.
- */
- void x_set_tripplebuffer(
- int wPageHeight
- )
- {
- if ( DoubleBufferActive || TrippleBufferActive ) {
- ErrorValue = ERROR;
- return;
- }
- VisiblePageIdx = 0;
- if ( wPageHeight > ( ScrnLogicalHeight / 3 ) ) {
- wPageHeight = ScrnLogicalHeight / 3;
- }
- ScrnLogicalHeight = wPageHeight;
- if ( BottomClip > ScrnLogicalHeight ) {
- BottomClip = ScrnLogicalHeight;
- }
- int iPageSize = ScrnLogicalHeight * ScrnLogicalByteWidth;
- VisiblePageOffs = Page0_Offs;
- Page1_Offs = HiddenPageOffs = Page0_Offs + iPageSize;
- Page2_Offs = WaitingPageOffs = Page1_Offs + iPageSize;
- NonVisual_Offs = Page2_Offs + iPageSize;
- TrippleBufferActive = TRUE;
-
- MaxScrollY = ScrnLogicalHeight - ScrnPhysicalHeight - SplitScrnVisibleHeight;
- ErrorValue = OK;
- }
-
- /*
- @func sets the new clipping rectangle for selected clipping functions
- */
- void x_set_cliprect(
- xScreenCoord_t wLeft, //@parm left edge of clipping rectangle
- xScreenCoord_t wTop, //@parm top edge of clipping rectangle
- xScreenCoord_t wRight, //@parm right edge of clipping rectangle
- xScreenCoord_t wBottom //@parm bottom edge of clipping rectangle
- )
- {
- //do x...
- if (wLeft > wRight) {
- int wTemp = wLeft;
- wLeft = wRight;
- wRight = wTemp;
- }
- LeftClip = wLeft;
- RightClip = wRight;
- //...then do y.
- if (wTop > wBottom) {
- int wTemp = wTop;
- wTop = wBottom;
- wBottom = wTemp;
- }
- TopClip = wTop;
- BottomClip = wBottom;
- }
-
- /*
- @func x_text_mode simply returns the user to 80x25 mode
- */
- void x_text_mode(
- void
- )
- {
- ClearVideoMemory();
- union REGS r;
- r.x.eax = 0x0003;
-
- int386(0x10, &r, &r);
- }
-
- /*
- @func Waits for the vertical refresh to end
- */
- void x_wait_vsync(
- void
- )
- {
- WaitVsyncStart();
- }
-
-